#ifndef EXCELPOI_HPP
#define EXCELPOI_HPP

#include <iostream>
#include <jni.h>
using namespace std;

#define USE_RINTERNALS
#define MAX_EXCEL_COLS 256

extern "C" {

#include <R.h>
#include <Rinternals.h>
#include <Rdefines.h>
#include <R_ext/Rdynload.h>


  // these get called when dll 
  // is loaded into memory or unloded
  // the name must match the dll name that
  // is ultimately created by make
  // i.e. it must be excelpoi.o or .dll
  void R_init_Rexcelpoi(DllInfo *info);
  void R_unload_Rexcelpoi(DllInfo *info);


  int JNI_init(void);

  /* test remove later */
  SEXP pDFdims(SEXP dataFrame);

  // externally visible
  SEXP R2xls(SEXP r_object, SEXP filename, SEXP worksheetName, SEXP writeColNms, 
             SEXP writeRowNms, SEXP formats, SEXP rowNameFormats, SEXP alignColNmsRight, SEXP freezePlanes);

  SEXP xls2R(SEXP filename, SEXP workSheets, SEXP writeColNms, SEXP rowNmsCol);


  SEXP readNamedRange(SEXP filename, SEXP rangeName);
}


// internal methods
jobject createExcelSheet(jobject WorkBook, char* sheetName);

int writeList(jobject workbook, SEXP r_list, int writeColNms, int writeRowNms, SEXP formats, int ALN_RIGHT, int FP);
int writeSheet(jobject workBook, jobject Sheet, SEXP r_object, int writeColNms, int writeRowNms);
int writeSheetAsMatrix(jobject workBook,jobject Sheet, SEXP matrix, int writeColNms, int writeRowNms);
int writeSheetAsTS(jobject workBook,jobject Sheet, SEXP matrix, int writeColNms);
int writeSheetAsVector(jobject workBook,jobject Sheet, SEXP r_vector, int writeColNms, int writeRowNms);
int writeSheetAsDataFrame(jobject workBook,jobject Sheet, SEXP dataFrame, int writeColNms, int writeRowNms);
void freeze(jobject sheet, int writeColNames, int writeRowNames);

void writeRowNames(jobject Sheet, SEXP rowNames, int writeColNms);
void writeColNames(jobject Sheet, SEXP colNames, int writeRowNms);
void writeDates2RowNames(jobject workbook, jobject Sheet, SEXP dates, int writeColNms);

SEXP readColNames(jobject Sheet, int colNamesRow);

string CvtJst_to_string(jstring jstr);
void writeCHARSEXP(jobject cell, SEXP r_string);
void writeChar(jobject cell, char *charValue);
jstring make_jstring(char* str);

void writeDouble(jobject cell, SEXP r_data, int index);
void writeDouble(jobject cell, double value, int index);
void writeInteger(jobject cell, SEXP r_data, int index);
void writeString(jobject cell, SEXP r_data, int index);
void writeCase(jobject cell, SEXP r_data, int index);

int getColCount(jobject sheet);

// functions for reading
SEXP readMultiSheets(jobject workbook, SEXP workSheetNames, int colNms, int rowNms);
SEXP readSheet(jobject sheet, int colNms, int rowNms);
int guessNumberOfCols(jobject sheet);
int findLastContiguous(jobject row);


// functions for formatting
void applyFormatsToWorksheet(jobject WorkBook, jobject sheet, SEXP formats, int WCN, int WRN);
void applyRowFormatsToWorksheet(jobject WorkBook, jobject sheet, SEXP formats, int WCN);
void applyStyleToColumn(jobject Sheet, int colNum, jobject style, int writeColNms, int writeRowNms);
void applyStyleToColumnLiteral(jobject Sheet, int colNum, jobject style, int offSet);
void applyStyleToRow(jobject Sheet, int rowNum, jobject style, int writeRowNms);
void rowAlignRight(jobject WorkBook, jobject Sheet, int rowNum, int writeRowNms);
void ExceptionCheck();

#endif // EXCELPOI_HPP
